/*
 * FtpContext.h
 *
 *  Created on: 2012-12-28
 *      Author: yangentao@gmail.com
 */

#pragma once;
#include <string>
#include <set>
#include "../yet/net/BaseSocket.h"
#include "../yet/StreamLog.h"
#include "../yet/AutoLock.h"
#include "../yet/ThreadHandler.h"

#include "Packet.h"
using namespace std;

namespace ftp {
using namespace yet;

//drwxr-xr-x 1 ftp ftp              0 Dec 28 23:46 a
//-rw-r--r-- 1 ftp ftp            161 Oct 30  2012 Main.java
class ListItemUnix {
public:
	ListItemUnix();
	ListItemUnix(const string& listitem);
	virtual ~ListItemUnix();
public:
	void parse(const string& listitem);
	bool isDir();
	string getName();
	int getSize(); //TODO u_long
	int getMonth();
	int getDay();
	int getYear(); //dir only
	int getHour(); //file only
	int getMinitue(); //file only
	string getUser();
	string getGroup();
	string getPrivilage();
private:
	void init();
public:
	string item;
	string privilage;
	bool dir;
	string user;
	string group;
	int size;
	int month;
	int day;
	int year;
	int hour;
	int minitue;
	string name;
};

class DataTransfer {
public:
	DataTransfer();
	virtual ~DataTransfer();
public:
	void beginTrans(void* arg);
	void waitFinish(DWORD timeout = INFINITE);
private:
	void msgHandler(Message& msg);
public:
	boost::function<bool(void* p)> OnTransfer;
public:
	BaseSocket dataSock; //data connection
	bool success;
	bool translating;
private:
	ThreadHandler dataThread; //
	AutoEvent dataEvent; //notify when message finish.

};

class FtpContext: public ThreadLock {
public:
	FtpContext();
	virtual ~FtpContext();
public:
	bool connect();
	bool recvControl(Packet* p);
	bool sendControl(Packet* p);
	bool sendRecvControl(Packet* p);


private:
	bool download(Message& msg);
	bool upload(Message& msg);
public:
	bool isUnix();
	bool isMsDos();
	bool isSupportCommand(string serverCommand);
	bool isSupportCommand(int ftpCommand);
	vector<string> getNlstItems();
	vector<ListItemUnix> getListItemsUnix();
public:
	boost::function<void(Packet* p)> OnWait;

public:
	LogConnection logConn;
	BaseSocket sock; //control connection
	DataTransfer dataTransfer;
	string host; //connect
	u_short port; //connect
	string username;
	string password;
	string account;
	string systData; //syst
	string pwd; //pwd
	set<string> serverCommands; //by help
	bool usePasv;
	string pasvIP; //pasv
	u_short pasvPort; //pasv
	u_short portPort; //port
	string listData; // list data
	bool listDataOK; //list data recv success
	string nlstData; // list data
	bool nlstDataOK; //list data recv success
private:
	AutoBuffer<char> buf; //for read
};

} /* namespace yet */
